package com.example.routeplansystem.service.impl;

import com.example.routeplansystem.constant.ResponseStatus;
import com.example.routeplansystem.dao.*;
import com.example.routeplansystem.entity.dto.ResponseEntity;
import com.example.routeplansystem.entity.po.NodePojo;
import com.example.routeplansystem.entity.po.Question;
import com.example.routeplansystem.entity.po.QuestionNodePojo;
import com.example.routeplansystem.entity.po.VehicleMessage;
import com.example.routeplansystem.service.*;
import com.example.routeplansystem.utils.DateUtil;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.example.routeplansystem.constant.ProcessState.*;

@Slf4j
@Service
public class QuestionServiceImp implements QuestionService {

    @Autowired
    private QuestionNodeDao questionNodeDao;

    @Autowired
    private QuestionDao questionDao;

    @Autowired
    private FinalSolutionService finalSolutionService;

    @Autowired
    private DistanceService distanceService;

    @Autowired
    private NodeService nodeService;

    @Autowired
    private NodeDao nodeDao;

    @Autowired
    private VehicleService vehicleService;

    @Autowired
    private VehicleDao vehicleDao;

    @Autowired
    private FinalSolutionDao finalSolutionDao;

    @Autowired
    private SolutionDao solutionDao;

    //添加问题：
    @Override
    public ResponseEntity<Integer> insertQuestion(Question question) {

        //检查问题名称重复：
        try {
            checkQuestionNameDuplicate(question);
        } catch (Exception e) {
            return new ResponseEntity<>(ResponseStatus.FAILURE_RESPONSE, e.getMessage(), null);
        }

        //添加问题到数据库：
        boolean flag = questionDao.insertQuestion(question);

        //判断数据库添加是否成功：
        if (flag) {
            return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "路径规划方案创建成功！！！", null);
        } else {
            return new ResponseEntity<>(ResponseStatus.FAILURE_RESPONSE, "路径规划方案创建失败！！！", null);
        }

    }

    //检查问题重复：
    private void checkQuestionNameDuplicate(Question question) throws RuntimeException {

        //获取参数信息：
        String questionName = question.getQuestionName();
        int userId = question.getUserId();

        //同一个用户下不能存在相同的问题名称：（问题方案名称查重）
        Question checkQuestion = questionDao.findQuestionByQuestionNameAndUserId(questionName, userId);

        if (null == checkQuestion) {
            log.info("------QuestionService(检测问题名称重复) 问题名称不重复 ------" + DateUtil.getFormatDate());
        } else {
            log.info("------QuestionService(检测问题名称重复) checkQuestion:" + checkQuestion + "------" + DateUtil.getFormatDate());

            throw new RuntimeException("问题名称已经被使用，请更换问题名称重试！！！");
        }
    }

    //获取用户问题列表：
    @Override
    public ResponseEntity<List<Question>> getQuestions(int userId, Integer currentPage, Integer pageSize) {
        //PageHelper：分页插件
        PageHelper.startPage(currentPage, pageSize);

        //数据库查询问题列表信息：
        List<Question> questionsByUserId = questionDao.findQuestionsByUserId(userId);

        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "查询路径规划方案成功！！！", questionsByUserId);
    }

    //删除问题：
    @Override
    @Transactional(rollbackFor = Exception.class) //异常回滚
    public ResponseEntity<String> removeQuestion(int questionId) {

        //删除当前问题的所有解决方案（final_solution和solution）：
        finalSolutionService.removeAllFinalSolutionByQuestionId(questionId);

        //删除距离表中记录（distance）
        distanceService.deleteDistanceByQuestionId(questionId);

        NodePojo nodePojo = new NodePojo();
        //  nodePojo.setQuestionId(questionId);

        nodeService.deleteNodeByQuestionId(questionId);
        vehicleService.removeVehicleByQuestionId(questionId);
        questionDao.deleteQuestion(questionId);

        return new ResponseEntity<>(ResponseStatus.SUCCESS_RESPONSE, "删除成功！！！", null);
    }

    @Override
    public void updateQuestion(Question question) {

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void copyQuestion(int questionId) throws CloneNotSupportedException {
        Question question = questionDao.findQuestionByQuestionId(questionId);
        Question questionClone = (Question) question.clone();
        List<QuestionNodePojo> questionNodeList = questionNodeDao.selectAllNode(questionId);
        if (!questionNodeList.isEmpty()) {
            List<Integer> nodeIdList = questionNodeList.stream().map(QuestionNodePojo::getNodeId).collect(Collectors.toList());
            List<NodePojo> nodes = nodeDao.selectNodeByIdList(nodeIdList);
            nodeDao.insertNodeBatch(nodes);
        }
        List<VehicleMessage> vehicleMessages = vehicleDao.searchVehicleByQuestionId(questionId);
        //  nodes.forEach(nodePojo -> nodePojo.setQuestionId(questionClone.getQuestionId()));
        vehicleMessages.forEach(vehicle -> vehicle.setQuestionId(questionClone.getQuestionId()));
        vehicleDao.insertVehiclesBatch(vehicleMessages);
        List<Integer> solutionIds = finalSolutionDao.findAllFinalSolutionId(questionId);

        boolean deleteSolutionFlag = solutionIds.stream().allMatch(solutionid ->
                solutionDao.deleteSolution(solutionid));

//        ServiceUtil.checkSqlExecuted(questionDao.insertQuestion(questionClone)
//                && nodeDao.insertNodeBatch(nodes) && vehicleDao.insertVehiclesBatch(vehicleMessages)
//                && finalSolutionDao.deleteFinalSolutionByQuestionId(questionId)
//                && deleteSolutionFlag);
    }

    @Override
    public Map<Integer, String> getExecutedAlgorithm(int questionId) {
        return getProrocessMap(questionId, COMPLETE_GENETIC, COMPLETE_SIMPLW, COMPLETE_NEW_GENETIC);
    }

    @Override
    public Map<Integer, String> getExecutingAlgorithm(int questionId) {
        return getProrocessMap(questionId, PROCESSING_GENETIC, PROCESSING_SIMPLE, PROCESSING_NEW_GENETIC);
    }

    @Override
    public Map<Integer, String> getNotExecuteAlgorithm(int questionId) {
        Question question = questionDao.findQuestionByQuestionId(questionId);
        Map<Integer, String> map = new HashMap<>();
        int generateState = question.getGeneticExecuted();
        int simpleState = question.getSimpleExecuted();
        int newGenerateState = question.getNewGeneticExecuted();
        if (generateState == 0) {
            map.put(2, "遗传算法");
        }
        if (simpleState == 0) {
            map.put(1, "简单算法");
        }
        if (newGenerateState == 0) {
            map.put(3, "优化算法");
        }
        return map;
    }

    public Map<Integer, String> getProrocessMap(int questionId, int state1, int state2, int state3) {
        Question question = questionDao.findQuestionByQuestionId(questionId);
        Map<Integer, String> map = new HashMap<>();
        int generateState = question.getGeneticExecuted();
        int simpleState = question.getSimpleExecuted();
        int newGenerateState = question.getNewGeneticExecuted();
        if (generateState == state1) {
            map.put(2, "遗传算法");
        }
        if (simpleState == state2) {
            map.put(1, "简单算法");
        }
        if (newGenerateState == state3) {
            map.put(3, "优化算法");
        }
        return map;
    }

}
